package util

import (
	"fmt"
	"log"
	"time"
)

func T_pipeline1()  {
	naturals := make(chan int)
	squares := make(chan int)

	go func() {
		for x :=1; ; x++ {
			naturals <- x
			if x == 10 {
				close(naturals)
				break
			}
			time.Sleep(500 * time.Millisecond)
		}
	}()

	//go func() {
	//	for {
	//		x := <- naturals // natural channel关闭了，这边还一直能收到0，这不很奇怪吗？
	//		squares <- x*x
	//		if x == 0 {
	//			close(naturals)
	//		}
	//	}
	//}()

	go func() {
		for {
			x, ok := <- naturals  // 由于这种snippet很常见，所以一般range <channel>来实现，当对端close后，接收端自动跳出
			if !ok {
				log.Print("natural channel closed and drained, break")
				break
			}
			squares <- x*x
		}
		close(squares)
	}()

	//for {
	//	fmt.Println(<-squares)
	//	time.Sleep(1 * time.Second)
	//}

	// 改用range channel的main goroutine; 不会出现不断接收到0的情况了
	for x := range squares {
		fmt.Println(x)
	}
}

// 使用单向channel
func T_pipeline3()  {
	counter := func(out chan<- int) {
		for x :=0; x < 10; x++ {
			log.Println("counter routine sending: ", x)
			out <- x
		}
		close(out)
	}

	squarer := func(out chan<- int, in <-chan  int) {
		for v := range in {
			log.Println("squares routine recv and send: ", v)
			out <- v * v
		}
		close(out)
	}

	printer := func(in <-chan int) {
		for v := range in {
			fmt.Println(v)
		}
	}

	naturals := make(chan int)
	squares := make(chan int)

	go counter(naturals)
	go squarer(squares, naturals)
	printer(squares)
}

// 8.4.4
func mirroredQuery() string {
	request := func(url string) string { return "NOT IMPLEMENTED"}
	resp := make(chan string, 3) // 如果这里用unbuffered channel，则在最快的响应来临时，另外2个goroutine还在阻塞中，这是bug
	go func() { resp <- request("baidu.com")}()
	go func() { resp <- request("163.com")}()
	go func() { resp <- request("sina.com")}()
	return <- resp //return the quickest response
}